package de.ihk.beans;

import java.io.IOException;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ComponentSystemEvent;

import org.apache.commons.mail.EmailException;
import org.primefaces.event.RowEditEvent;


import de.ihk.data.Aufgabe;
import de.ihk.data.Bearbeiter;
import de.ihk.data.Test;
import de.ihk.data.subtask.Seite;
import de.ihk.data.subtask.Sichtkontrolle;
import de.ihk.datamanagment.Mailer;
import de.ihk.datamanagment.MysqlConnector;

@ManagedBean(name = "loginBean")
@SessionScoped
public class LoginBean implements Serializable {
	private static final long serialVersionUID = 1L;
	private int id;

	private String name;
	private String vorname;
	private String username;
	private String password;
	private int superadmin = 0;
	private boolean isLoggedIn;
	private String pwRecoveryEMail;

	// Testbearbeitung
	private Test selectedTest;
	private Aufgabe selectedAufgabe;
	private List<Seite> seiten;
	private List<Sichtkontrolle> sichtkontrollen;
	private int aktuellLfdNr = 1;
	private String punktes;
	private Sichtkontrolle[] selectedSichtkontrollen;

	private Seite aktuelleSeite;
	private Seite[] selectedSeiten;

	private List<Bearbeiter> bearbeiters = new ArrayList<Bearbeiter>();

	private ResultSet rs = null;
	private MysqlConnector conn = null;
	private Mailer mail;

	public LoginBean() {
		conn = new MysqlConnector();

		try {
			mail = new Mailer();
		} catch (EmailException e) {
			e.printStackTrace();
		}
	}

	public String login() {
		// default url in case of login failure;
		String url = "login.xhtml";
		FacesMessage msg = null;
		try {
			rs = conn.checkLogin();
		} catch (SQLException e) {
			e.printStackTrace();
		}

		try {
			while (rs.next()) {
				if (username.equals(rs.getString(4)) && password.equals(rs.getString(5))) {
					isLoggedIn = true;
					id = rs.getInt(1);
					name = rs.getString(2);
					vorname = rs.getString(3);
					superadmin = rs.getInt(6);
					msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Welcome ", username);
					FacesContext.getCurrentInstance().addMessage(null, msg);
					return "hauptmenu.xhtml";
				}

			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Login Error", "Username oder Password falsch!");
		FacesContext.getCurrentInstance().addMessage(null, msg);
		return url;

	}

	/**
	 * An event listener for redirecting the user to login page if he/she is not
	 * currently logged in
	 * 
	 * @param event
	 */
	public void verifyUseLogin(ComponentSystemEvent event) {
		System.out.println(isLoggedIn);
		if (!isLoggedIn) {
			doRedirect("login.xhtml");
		}
	}

	public void verifySuperadminLogin(ComponentSystemEvent event) {
		FacesMessage msg = null;

		if (!isLoggedIn) {
			doRedirect("login.xhtml");
		}
		if (superadmin == 0) {

			// TODO Message richtig anzeigen
			msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Kein Zugriff", "Dieser Bereich ist nur für Hauptadmins!");
			FacesContext.getCurrentInstance().addMessage(null, msg);
			doRedirect("hauptmenu.xhtml");
		}
	}

	public void logout(ActionEvent actionEvent) {
		isLoggedIn = false;
		superadmin = 0;
		doRedirect("login.xhtml");
	}

	/**
	 * Method for redirecting a request
	 * 
	 * @param url
	 */
	public void doRedirect(String url) {
		try {
			FacesContext context = FacesContext.getCurrentInstance();
			context.getExternalContext().redirect(url);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public Bearbeiter getBearbeiterById(String value) {
		System.out.println("Starting to Check by ID");
		for (Bearbeiter be : bearbeiters) {
			System.out.println("be.toString=" + be.toString() + " // " + "value");
			if (be.toString().equals(value)) {
				return be;
			}
		}
		System.out.println("NO MATCH FOUND!");
		return null;

	}

	public void pwRecovery(ActionEvent actionEvent) throws SQLException {
		System.out.println("PW RECOVERY!");
		rs = conn.getAdmins();
		FacesMessage msg = null;
		boolean eMailFound = false;
		while (rs.next()) {
			if (pwRecoveryEMail.equals(rs.getString(4))) {
				eMailFound = true;
				try {
					mail.sendPassword(rs.getString(4), rs.getString(5));
				} catch (EmailException e) {
					e.printStackTrace();
				}
			}
		}
		if (eMailFound) {
			msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "E-Mail gefunden!", "Password wurde an ihre E-Mail versendet!");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		} else {
			msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "E-Mail nicht gefunden!", "Bitte eingegebene E-Mail überprüfen!");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}
	}

	public void debugAufgabe(ActionEvent actionEvent) throws SQLException, ClassNotFoundException, IOException {

		Seite kon = new Seite(seiten.size() + 1, "Bewertungsbogen Durchführung", Seite.Typ.SICHTKONTROLLE, "10-9-7-5-4-0 Punkte");
		// kon.setListe(liste);
		seiten.add(kon);
	}

	public void speichereAufgabe(ActionEvent actionEvent) throws SQLException {
		System.out.println("DELETE FROM aufgaben WHERE id = " + selectedAufgabe.getId() + ";");
		conn.mysqlUpdateQuery("DELETE FROM aufgaben WHERE id = " + selectedAufgabe.getId() + ";");
		selectedAufgabe.setSeiten(seiten);
		conn.addAufgabenObjectToDb(selectedAufgabe.getId(), selectedAufgabe.getClass().getName(), selectedAufgabe);
		System.out.println("Update Aufgabe");
		doRedirect("tests.xhtml");
	}

	public void verwerfeAufgabe(ActionEvent actionEvent) {
		doRedirect("tests.xhtml");
	}

	public void newSicht(ActionEvent actionEvent) {
		aktuelleSeite = new Seite(seiten.size() + 1, "Bewertungsbogen Durchführen", Seite.Typ.SICHTKONTROLLE,
				"Punksteschlüssel: 10-9-7-5-4-0 Punkte");
		punktes = "Punksteschlüssel: 10-9-7-5-4-0 Punkte";
		sichtkontrollen = aktuelleSeite.getListe();
		aktuellLfdNr = 0;
		doRedirect("neueseiten/neuesicht.xhtml");
	}

	public void bearbeiteSelectedSeite(ActionEvent actionEvent) {
		FacesContext context = FacesContext.getCurrentInstance();
		if (selectedSeiten.length == 0) {
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Fehler", "Bitte eine Seite auswählen!"));
		} else if (selectedSeiten.length > 1) {
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Fehler", "Bitte nur eine Seite auswählen!"));
		} else if (selectedSeiten[0].getTyp() == Seite.Typ.SICHTKONTROLLE) {
			punktes = selectedSeiten[0].getPunkteschluessel();
			aktuelleSeite = selectedSeiten[0];
			seiten.remove(aktuelleSeite);
			sichtkontrollen = aktuelleSeite.getListe();
			for (Sichtkontrolle sicht : aktuelleSeite.getListe()) {
				if (sicht.getLfdNr() >= aktuellLfdNr) {
					aktuellLfdNr = sicht.getLfdNr();
				}
			}
			doRedirect("neueseiten/neuesicht.xhtml");
		}
	}

	public void newEntry(ActionEvent actionEvent) {
		aktuellLfdNr++;
		System.out.println("DIE 1");
		sichtkontrollen.add(new Sichtkontrolle(aktuellLfdNr, "1-35", "Test"));
		System.out.println("DIE 2");
	}

	public void deleteSichtAll(ActionEvent actionEvent) {
		sichtkontrollen.clear();
	}

	public void deleteSichtSelected(ActionEvent actionEvent) {
		for(Sichtkontrolle s: selectedSichtkontrollen){
			sichtkontrollen.remove(s);
		}
	}

	public void speichereSicht(ActionEvent actionEvent) {
		aktuellLfdNr = 0;
		seiten.add(aktuelleSeite);
		doRedirect("../bearbeitetest.xhtml");

	}
	
	//TODO Seite Maßkontrolle einbinden	
	public void newMas(ActionEvent actionEvent) {

	}
	
	//TODO Seite einbinden
	public void newGewichtet(ActionEvent actionEvent) {

	}
	
	//TODO Seite einbinden
	public void newGespraech(ActionEvent actionEvent) {

	}

	public void deleteSeitenAll(ActionEvent actionEvent) {
		seiten.clear();
	}

	public void deleteSeitenSelected(ActionEvent actionEvent) {
		for (Seite s : selectedSeiten) {
			seiten.remove(s);
		}

	}

	public void onEdit(RowEditEvent event) {
		FacesMessage msg = new FacesMessage("Seite editiert.", Integer.toString(((Seite) event.getObject()).getId()));

		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	public void onCancel(RowEditEvent event) {
		FacesMessage msg = new FacesMessage("Editieren abgebrochen.", Integer.toString(((Seite) event.getObject()).getId()));

		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	public void onEditSicht(RowEditEvent event) {
		FacesMessage msg = new FacesMessage("Seite editiert.", Integer.toString(((Sichtkontrolle) event.getObject()).getLfdNr()));

		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	public void onCancelSicht(RowEditEvent event) {
		FacesMessage msg = new FacesMessage("Editieren abgebrochen.", Integer.toString(((Sichtkontrolle) event.getObject()).getLfdNr()));

		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	// -- GETTER UND SETTER

	public String getUsername() {
		return username;
	}

	public List<Bearbeiter> getBearbeiters() {
		return bearbeiters;
	}

	public void setBearbeiters(List<Bearbeiter> bearbeiters) {
		this.bearbeiters = bearbeiters;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public boolean isLoggedIn() {
		return isLoggedIn;
	}

	public void setLoggedIn(boolean isLoggedIn) {
		this.isLoggedIn = isLoggedIn;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getVorname() {
		return vorname;
	}

	public void setVorname(String vorname) {
		this.vorname = vorname;
	}

	public int getSuperadmin() {
		return superadmin;
	}

	public void setSuperadmin(int superadmin) {
		this.superadmin = superadmin;
	}

	public String getPwRecoveryEMail() {
		return pwRecoveryEMail;
	}

	public void setPwRecoveryEMail(String pwRecoveryEMail) {
		this.pwRecoveryEMail = pwRecoveryEMail;
	}

	public Test getSelectedTest() {
		return selectedTest;
	}

	public void setSelectedTest(Test selectedTest) {
		this.selectedTest = selectedTest;
	}

	public Aufgabe getSelectedAufgabe() {
		return selectedAufgabe;
	}

	public void setSelectedAufgabe(Aufgabe selectedAufgabe) {
		this.selectedAufgabe = selectedAufgabe;
		seiten = selectedAufgabe.getSeiten();
	}

	public List<Seite> getSeiten() {
		return seiten;
	}

	public void setSeiten(List<Seite> seiten) {
		this.seiten = seiten;
	}

	public List<Sichtkontrolle> getSichtkontrollen() {
		return sichtkontrollen;
	}

	public void setSichtkontrollen(List<Sichtkontrolle> sichtkontrollen) {
		this.sichtkontrollen = sichtkontrollen;
	}

	public Seite getAktuelleSeite() {
		return aktuelleSeite;
	}

	public void setAktuelleSeite(Seite aktuelleSeite) {
		this.aktuelleSeite = aktuelleSeite;
	}

	public Seite[] getSelectedSeiten() {
		return selectedSeiten;
	}

	public void setSelectedSeiten(Seite[] selectedSeiten) {
		this.selectedSeiten = selectedSeiten;
	}

	public String getPunktes() {
		return punktes;
	}

	public void setPunktes(String punktes) {
		this.punktes = punktes;
	}

	public Sichtkontrolle[] getSelectedSichtkontrollen() {
		return selectedSichtkontrollen;
	}

	public void setSelectedSichtkontrollen(Sichtkontrolle[] selectedSichtkontrollen) {
		this.selectedSichtkontrollen = selectedSichtkontrollen;
	}

}